﻿using Coldairarrow.Entity.Base_Manage;
using Coldairarrow.Entity.DTO;
using Coldairarrow.Entity.PB;
using Coldairarrow.IBusiness;
using Coldairarrow.Util;
using EFCore.Sharding;
using LinqKit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Dynamic.Core;
using System.Linq.Expressions;
using System.Threading.Tasks;

namespace Coldairarrow.Business.PB
{
    public partial class PB_LabourServicesBusiness : BaseBusiness<PB_LabourServices>, IPB_LabourServicesBusiness, ITransientDependency
    {
        readonly IOperator _operator;
        public PB_LabourServicesBusiness(IDbAccessor db, IOperator @operator)
            : base(db)
        {
            _operator = @operator;
        }

        #region 外部接口

        public async Task<PageResult<LabourServiceDTO>> GetDataListAsync(PageInput<ConditionDateAreaDTO> input)
        {
            //var q = GetIQueryable();
            var where = LinqHelper.True<PB_LabourServices>();
            //var search = input.Search;

            ////筛选
            //if (!search.Condition.IsNullOrEmpty() && !search.Keyword.IsNullOrEmpty())
            //{
            //    var newWhere = DynamicExpressionParser.ParseLambda<PB_LabourServices, bool>(
            //        ParsingConfig.Default, false, $@"{search.Condition}.Contains(@0)", search.Keyword);
            //    where = where.And(newWhere);
            //}

            //return await q.Where(where).GetPageResultAsync(input);
            Expression<Func<PB_LabourServices, PB_ProcecureSub, Base_User, LabourServiceDTO>> select = (a, b, c) => new LabourServiceDTO
            {
                Id=a.Id,
                ProcecureName= b.Name,
                RealName=c.RealName,
                OperationDate=a.OperationDate,
                Type= a.Type,
                Remark=a.Remark,
                WeightTotal=Convert.ToDouble(a.WeightTotal),
                SingleSettlement=a.SingleSettlement,
                Hours=a.Num
            };
            var search = input.Search;
            select = select.BuildExtendSelectExpre();
            var q_LabourServices = GetIQueryable();
            var q = from a in q_LabourServices.AsExpandable()
                    join b in Db.GetIQueryable<PB_ProcecureSub>() on a.ProcecureSubId equals b.Id into ab
                    from b in ab.DefaultIfEmpty()
                    join c in Db.GetIQueryable<Base_User>() on a.OperatorId equals c.Id into ac
                    from c in ac.DefaultIfEmpty()
                    select @select.Invoke(a, b, c);

            if (!search.Keyword.IsNullOrEmpty())
            {
                var keyword = $"%{search.Keyword}%";
                q = q.Where(x =>
                      EF.Functions.Like(x.RealName, keyword));
            }
            if (!search.StartDate.IsNullOrEmpty())
            {
                q = q.Where(x => x.OperationDate >= Convert.ToDateTime(search.StartDate));
            }
            if (!search.EndDate.IsNullOrEmpty())
            {
                q = q.Where(x => x.OperationDate <= Convert.ToDateTime(search.EndDate));
            }

            return await q.GetPageResultAsync(input);
        }

        public async Task<PB_LabourServices> GetTheDataAsync(string id)
        {
            return await GetEntityAsync(id);
        }

        public async Task AddDataAsync(LabourServicesInputDTO data)
        {
            List<PB_LabourServices> pB_LabourServices = new List<PB_LabourServices>();
            string Items = IdHelper.GetId();
            double subWeightTotal = 0;
            double subHourTotal = 0;
            foreach (var item in data.subData)
            {
                PB_LabourServices service =new PB_LabourServices();
                service.Id = IdHelper.GetId();
                service.CreatorId = data.CreatorId;
                service.CreateTime = data.CreateTime;
                service.Deleted = data.Deleted;
                service.ProcecureSubId = data.ProcecureSubId;
                service.Num = item.Hour.IsNullOrEmpty() ? 0 : Convert.ToDouble(item.Hour);
                service.OperatorId = item.UserId;
                service.OperationDate = data.OperationDate;
                service.Remark = data.Remark;
                service.Type = data.Type;
                service.WeightTotal = item.Weight.IsNullOrEmpty() ? 0 : Convert.ToDouble(item.Weight);
                if (data.SingleSettlement==1)
                {
                    service.WeightTotal = data.WeightTotal / Convert.ToDouble(item.Weight);
                }
                service.Items = Items;
                service.SingleSettlement=data.SingleSettlement;
                pB_LabourServices.Add(service);
                subWeightTotal += Convert.ToDouble(item.Weight);
                subHourTotal += Convert.ToDouble(item.Hour);
            }
            if (String.Format("%.2f", subWeightTotal) != String.Format("%.2f", data.WeightTotal))
            {
                throw new BusException("重量不符合要求！");
            }
            if (String.Format("%.2f", subHourTotal) != String.Format("%.2f", data.Num))
            {
                throw new BusException("工时不符合要求！");
            }
            await InsertAsync(pB_LabourServices);
        }

        public async Task UpdateDataAsync(LabourServicesInputDTO data)
        {
            await UpdateAsync(data);
        }

        public async Task DeleteDataAsync(List<string> ids)
        {
            await DeleteAsync(ids);
        }

        #endregion

        #region 私有成员

        #endregion
    }
}